home *** CD-ROM | disk | FTP | other *** search
- Citrix-pa-scan:
- This tool should be used to enumerate Citrix published applications.
-
- #!/usr/bin/perl
- use Socket;
-
- $SIG{ALRM}=sub { $connection=0; close(CON); };
- $trick_master=
- "\x20\x00\x01\x30\x02\xFD\xA8\xE3" .
- "\x00\x00\x00\x00\x00\x00\x00\x00" .
- "\x00\x00\x00\x00\x00\x00\x00\x00" .
- "\x00\x00\x00\x00\x00\x00\x00\x00"
- ;
-
- $get_pa=
- "\x2a\x00\x01\x32\x02\xfd" .
- "\xa8\xe3\x00\x00\x00\x00" .
- "\x00\x00\x00\x00\x00\x00" .
- "\x00\x00\x00\x00\x00\x00" .
- "\x00\x00\x00\x00\x21\x00" .
- "\x02\x00\x00\x00\x00\x00" .
- "\x00\x00\x00\x00\x00\x00"
- ;
-
- $|=1;
-
- print "\nCitrix Published Application Scanner version 2.0\
- By Ian Vitek, ian.vitek\@ixsecurity.com\n";
-
- die "\nUsage: $0 {IP | file | - | random } [timeout]\
- \tIP\tIP to test\
- \tfile\tRead IPs from file\
- \t-\tRead IPs from standard input\
- \trandom\tRead IPs from /dev/urandom\
- \ttimeout\tTimeout\
- \n" if(!$ARGV[0]);
-
- $input=$ARGV[0];
- $timeout=$ARGV[1];
- $timeout=1 if(!$timeout);
- if($input eq "-" || -r $input) {
- open(INPUTFD,"$input") or die "Cant open file $input: $!\n";
- $newHost=2;
- } elsif ($input eq "random") {
- open(RANDOM,"/dev/urandom") or die "Cant open /dev/urandom: $!\n";
- binmode(RANDOM);
- $newHost=3;
- } else {
- $newHost=1;
- }
-
- $loop=1;
- while($loop==1) {
- undef $target;
- if($newHost==2) {
- $target=<INPUTFD> or exit;
- chomp $target;
- $target=~s/\s*(\S+)/$1/;
- redo if(!$target);
- } elsif ($newHost==1) {
- $loop=0;
- $target=$input;
- } elsif ($newHost==3) {
- undef @ch;
- $i=0;
- while($i<4) {
- while($ch[$i] < 1 || $ch[$i] > 254) {
- $ch[$i]=ord getc(RANDOM);
- }
- $i++;
- }
- $target=sprintf("%d.%d.%d.%d",$ch[0],$ch[1],$ch[2],$ch[3]);
- } else {
- die "Nothing to do? Check input!\n\n";
- }
-
- #
- # Get Master Browser
- #
- $server=inet_aton($target) or die "Is \"${target}\" a target?\n\n";
- $retry=0;
- $connection=0;
- while($retry++<2 and $connection==0) {
- $connection=1;
- socket(CON, PF_INET, SOCK_DGRAM, getprotobyname('udp'));
- send(CON, $trick_master, 0, sockaddr_in(1604, $server));
- alarm $timeout;
- $from_CON=recv(CON,$data,1500,0);
- alarm 0;
- }
- close(CON);
- if($connection==0) {
- print "$target not responding\n";
- next;
- }
- undef $master_raw;
- undef $master;
- ($master_raw)=$data=~/.+\x02\x00\x06\x44(....)/s;
- if($master_raw) {
- $master=sprintf("%d.%d.%d.%d",ord substr($master_raw,0,1),ord
- substr($master_raw,1,1),ord substr($master_raw,2,1),ord
- substr($master_raw,3,1));
- } else {
- $master="ERROR";
- }
- print "$target|$master";
- if($target eq $master) {
- print "|1|";
- } else {
- print "|0|";
- }
-
- #
- # Enumerate PA
- #
- $retry=0;
- $connection=0;
- while($retry++<2 and $connection==0) {
- $connection=1;
- socket(CON, PF_INET, SOCK_DGRAM, getprotobyname('udp'));
- send(CON, $get_pa, 0, sockaddr_in(1604, $server));
- alarm $timeout;
- undef $data;
- $from_CON=recv(CON,$data,1500,0);
- alarm 0;
- }
- if($connection==0) {
- print "Connection lost\n";
- next;
- }
- undef $pa;
- $pa=substr($data,40);
- chop $pa;
- $pa=~s/\x00/\;/sg;
- print "$pa";
-
- #
- # More packets?
- #
- $last_packet=ord substr($data,30,1);
- while($last_packet==0) {
- $connection=1;
- alarm $timeout*2;
- undef $data;
- $from_CON=recv(CON,$data,1500,0);
- alarm 0;
- if($connection==0) {
- print ",ERROR";
- last;
- }
- undef $pa;
- $pa=substr($data,39);
- chop $pa;
- $pa=~s/\x00/\;/sg;
- print "$pa";
- $last_packet=ord substr($data,30,1);
- }
- close(CON);
- print "\n";
- }
-
- Citrix-pa-proxy:
- This tool should be used to enumerate and connect to a published
- application with the Citrix client when the master browser is non-public.
-
- #!/usr/bin/perl
- use Socket;
-
- die "\
- * citrix-pa-proxy 2.0 by Ian.Vitek\@ixsecurity.com *\
- usage: $0 IP_to_proxy_to [Local_ip]\
- \
- " if(@ARGV==0);
-
- $timeout=2;
- $server_ip=$ARGV[0];
- $proxy_ip="127.0.0.1";
- if($ARGV[1]) {
- $proxy_ip=$ARGV[1];
- $timeout=4;
- }
- $server=inet_aton($server_ip);
- $proxy=inet_aton($proxy_ip);
- $pa_connect=1;
- while(1) {
- close(CON1);
- socket(CON1, PF_INET, SOCK_DGRAM, getprotobyname('udp'));
- bind(CON1, sockaddr_in(1604,INADDR_ANY));
- $from_CON1=recv(CON1,$data1,1500,0);
- ($from_CON1_port,$from_CON1_ip)=sockaddr_in($from_CON1);
- if(substr($data1,3,5) eq "\x32\x02\xfd\xa8\xe3" && $pa_connect) {
- $pa_connect=0;
- warn("- Hey! This is a PA enumerate session.\n");
- warn("- Closing. Try to enumerate again.\n");
- redo;
- }
- if($pa_connect) {
- warn("PA connect from " . inet_ntoa($from_CON1_ip) . ":" .
- $from_CON1_port . "\n");
- } else {
- warn("PA enumerate from " . inet_ntoa($from_CON1_ip) . ":" .
- $from_CON1_port . "\n");
- }
- $connection=0;
- $retry=0;
- $SIG{ALRM}=sub { $connection=0; close(CON2); };
- while($retry++<3 and $connection==0) {
- socket(CON2, PF_INET, SOCK_DGRAM, getprotobyname('udp'));
- $connection=1;
- alarm $timeout;
- warn("Sending request to $server_ip:1604\n");
- send(CON2, $data1, 0, sockaddr_in(1604,$server));
- alarm 0;
- }
- if($connection==0) {
- warn("No connection to $server_ip\n\n");
- close(CON1);
- next;
- }
- alarm $timeout;
- $from_CON2=recv(CON2,$data2,1500,0);
- alarm 0;
- close(CON2);
- if($connection==0) {
- warn("No answer from $server_ip\n\n");
- close(CON1);
- next;
- } else {
- warn("Got answer from $server_ip\n");
- }
- if(substr($data2,0,1) eq "\x30" && $pa_connect) {
- $data2=~s/\x02\x00\x06\x44(.)(.)(.)(.)/\x02\x00\x06\x44$proxy/sg;
- $spoof=sprintf("%d.%d.%d.%d",ord $1,ord $2,ord $3,ord $4);
- warn("- Changing $spoof to $proxy_ip\n");
- } else {
- $data2=~s/\x02\x00\x06\x44(.)(.)(.)(.)/\x02\x00\x06\x44$server/sg;
- $spoof=sprintf("%d.%d.%d.%d",ord $1,ord $2,ord $3,ord $4);
- $data2=~s/\x02\x00\x05\xd6..../\x02\x00\x05\xd6$server/sg
- if($pa_connect);
- warn("- Changing $spoof to $server_ip\n");
- $pa_connect=1;
- }
- warn("Proxying\n");
- $SIG{ALRM}=sub { $connection=0; close(CON1); };
- alarm $timeout;
- send(CON1, "$data2", 0, $from_CON1);
- alarm 0;
- close(CON1);
- if($connection==0) {
- warn("No connection to client\n\n");
- close(CON1);
- next;
- } else {
- warn("Done\n\n");
- }
-
- }
-
- Pas:
- This tool should be used to connect to the applications reported by
- citrix-pa-scan.pl.
-
- #!/usr/bin/perl
- $|=1;
- open(INDATA, "pas.wri") or die "Cant read data file: $!\n";
- open(RESULT, ">pas_results.wri") or die "Cant create result file: $!\n";
- while($line=<INDATA>) {
- chomp $line;
- next if( $line!~/^(\d+\.\d+\.\d+\.\d+)\|\d+\.\d+\.\d+\.\d+\|[01]\|(.+)/
- );
- $ip=$1;
- @pa=split(';',$2);
- foreach $test_pa (@pa) {
- open(TEMPLATE,"template.ica") or die "Cant open template file: $!\n";
- open(ICA,">ica.ica") or die "Cant create ica file; $!\n";
- while($tline=<TEMPLATE>) {
- $tline=~s/IPIPIP/$ip/;
- $tline=~s/PAPAPA/$test_pa/;
- print ICA $tline;
- }
- close(ICA);
- system('ica.ica');
- $result=0;
- while($result < 1 || $result > 5) {
- print "\nHow did the connect to $test_pa on $ip go?\n";
- print "1: Wery well, anonymous login, but no desktop.\n";
- print "2: Anonymous and vulnerable.\n";
- print "3: Login required.\n";
- print "4: Error. No connection or similar.\n";
- print "\n";
- print "5: Redo\n";
- print "> ";
- $result=<>;
- chomp $result;
- }
- redo if($result==5);
- print RESULT "$ip\|$test_pa|$result\n";
-
- }
- }
-
- template.ica:
- (Needed by pas.pl)
-
- [WFClinet]
- Version=2
- ClientName=testClient
-
- [ApplicationServers]
- PAPAPA=
-
- [PAPAPA]
- Address=IPIPIP
- InitialProgram=#PAPAPA
- TransportDriver=TCP/IP
- WinStationDriver=ICA 3.0
- DesiredHRES=800
- DesiredVRES=600
-
-